// 10-排序6 Sort with Swap(0, i)
#include <stdio.h>
#include <stdlib.h>
#define MaxSize 100000

// 输入数组a，给数组t赋值 t[a[i]] = i
void inputAT(int a[], int t[], int n) {
    for (int i=0; i<n; i++) {
        scanf("%d", &a[i]);
        t[a[i]] = i;
    }
}

void printArray(int a[], int n) {
    if (n < 1 || a == NULL) {
        return;
    }
    printf("%d", *a++);
    for (int i=1; i<n; i++) {
        printf(" %d", *a++);
    }
    printf("\n");
}

// 方法一：只用0做交换来排序，记录交换次数
int f1(int a[], int t[], int n) {
    int count = 0;
    for (int i=0; i<n; i++) {
        if (a[i] != i) {
            while (a[0] != 0) {
                int tmp = a[0];
                a[0] = a[tmp];
                a[tmp] = tmp;
                count++;
            }
            if (a[i] != i) {
                int tmp = a[0];
                a[0] = a[i];
                a[i] = tmp;
                count++;
            }
        }
    }
    return count;
}

// 方法二：使用标记数组，做排序，计算环内元素个数
int f2(int a[], int t[], int n) {
    int count = 0;
    for (int i=0; i < n; i++) {
        if (a[i] == i) {
            continue;
        }
        int tmp = a[i];
        int j = i;
        // 记录环内元素个数
        int circleCount = 1;
        // 记录是否有0
        int have0 = 0;
        while (t[j] != i) {
            a[j] = a[t[j]];
            j = t[j];
            circleCount++;
            if (t[j] == 0) {
                // 有0
                have0 = 1;
            }
        }
        a[j] = tmp;
        // 包括0：需要n0–1次交换
        // 不包括0：先把0换到环里，再进行(ni+1)–1次交换 —— 一共是ni+1次交换
        count += circleCount + (have0 ? -1 : 1);
    }
    return count;
}

// 方法三：使用公式 N-S+K-2
int f3(int a[], int t[], int n) {
    // 第0个元素是0，减去0，否则减去2
    int firstIs0 = (a[0] == 0);
    int count = 0;
    // 单元环个数
    int s = 0; 
    for (int i=0; i<n; i++) {
        if (a[i] == i) {
            s++;
        }
    }
    // 多元环个数
    int k = 0;
    for (int i=0; i<n; i++) {
        if (t[i] == i) {
            continue;
        }
        // 环开始位置 i
        int j = i;
        // 直到环结束，即 t[j] == i 时回到开始位置
        while (t[j] != i) {
            // 记录 j 
            int preJ = j;
            // 移动 j 到 t[j] 位置
            j = t[j];
            // 设置该元素已经访问过
            t[preJ] = preJ; 
        }
        t[j] = j;
        k++;
    }
    return n-s+k-(firstIs0 ? 0 : 2);
}

int main() {
    int a[MaxSize];
    int t[MaxSize];
    int n;
    scanf("%d", &n);
    if (n < 1) {
        printf("0");
    }
    inputAT(a, t, n);
    int count = f2(a, t, n);
    // printArray(a, n);
    printf("%d", count);
    return 0;
}
